package com.nightpiter.model.objects;

import com.nightpiter.exceptions.TimeFormatException;

/**
 * Time class
 * 
 * working with Time typed values
 * 
 * @author Eldar Abusalimov (eldar.abusalimov@gmail.com)
 * @author Ilya Shourigyn (honorik@gmail.com)
 * 
 */

public class Time {

	private int seconds;
    private int minutes;
    private int hours;

    /**  
     * @param hours  - Hours
     * @param minutes - Minutes
     * @param seconds - Seconds
     */
    public Time(int hours,int minutes, int seconds){
        this.seconds=seconds%60;
        this.minutes=(minutes%60+seconds/60)%60;
        this.hours=hours+seconds/3600+minutes/60;
    }

    /**
     * 
     * @param seconds - Time in seconds
     */
    public Time(int seconds){
        this.seconds=seconds%60;
        this.minutes=(seconds/60)%60;
        this.hours=hours+seconds/3600;
    }    

    /**
     * 
     * @param strTime time in format "hh::mm::ss" or "mm::ss" or "ss"
     * @throws TimeFormatException - in case of wrong time format
     */    
    public Time(String strTime) throws TimeFormatException {

		String[] strTimeParts = strTime.split(":");

        switch (strTimeParts.length) {
        case 1:
            seconds = Integer.parseInt(strTimeParts[0]);
            break;
        case 2:
            minutes = Integer.parseInt(strTimeParts[0]);
            seconds = Integer.parseInt(strTimeParts[1]);
            break;
        case 3:
            hours = Integer.parseInt(strTimeParts[0]);
            minutes = Integer.parseInt(strTimeParts[1]);
            seconds = Integer.parseInt(strTimeParts[2]);
            break;
        default:
        	throw new TimeFormatException();
        }


    }    
    
    /**      
     * hh - hours always with 2 chars
     * mm-minutes always with 2 chars
     * ss-seconds always with 2 chars
     * 0hh(<text>) - print text in () and hours only if not null
     * 0mm(<text>) - print text in () and hours only if not null
     * 0ss(<text>) - print text in () and hours only if not null
     * 
     * @param format string with "hh", "mm" and "ss" in place of hours, minutes and seconds
     * @return formated time in string
     */
    public String toFormatedString(String format) {
    	
    	format = removeTextIfTimeIsNullOrReplace(format,"0hh", hours);
    	format = removeTextIfTimeIsNullOrReplace(format,"0mm", minutes);
    	format = removeTextIfTimeIsNullOrReplace(format,"0ss", seconds);
    	format=format.replaceAll("hh", this.formatIntString(this.hours));
    	format=format.replaceAll("mm", this.formatIntString(this.minutes));
    	format=format.replaceAll("ss", this.formatIntString(this.seconds));  
    	//format=format.replaceAll("h", Integer.toString(this.hours));    	
    	//format=format.replaceAll("m", Integer.toString(this.minutes));
    	//format=format.replaceAll("s", Integer.toString(this.seconds));    	  	
    	return format;
    }
    
    /**
     * removes text and time if time is null
     * @param str string with substrings to replace
     * @param format - substring to replace
     * @param time time to insert instead of format
     * @return formated string
     */
	private String removeTextIfTimeIsNullOrReplace(String str, String format, int time) {
		format+="(";
		str+="";
		while(str.indexOf(format)!=-1) {
			int begin = str.indexOf(format);
			int end =str.indexOf(')', begin);
			if(time==0) {	    		
	    		if(begin!=-1) {
	    			if(end!=-1) {
	    				str=str.substring(0, begin) + str.substring(end+1);
	    			} else {
	    				str=str.substring(0, end)+str.substring(end+1);;
	    				str=str.replaceFirst(format, "");	    				
	    			}
	    		}
	    	} else {
	    		str=str.replaceFirst(format, this.formatIntString(time));
	    	}
		}
		return str;
	}
	
    
    /** 
     * @param format string with "hh", "mm" and "ss" in place of hours, minutes and seconds
     * @return formated time in string
     */
    
    public static String toFormatedString(String format, int timeInSeconds) {
    	Time time = new Time(timeInSeconds);
    	return time.toFormatedString(format);
    }
    /**
     * Represent Time as string in format "h:mm:ss" if Hours is more then null, 
     * and "mm:ss" in other way
     */
    public String toString() {
		String result = "";
		if (hours != 0) {
			result += hours + ":";
		}		
		result += this.formatIntString(minutes)+":";
		result += this.formatIntString(seconds);
        return result;
    }

	private String formatIntString(int integer) {
		String result = "";
		if (integer < 10) {
			result += "0";
		}
		result+=Integer.toString(integer);
		return result;
	}
    
    public int getHours() {
    	return this.hours;
    }
    public int getMinutes() {
    	return this.minutes;
    }
    public int getSeconds() {
    	return this.seconds;
    }

    /**
     * 
     * @param strTime time in format "hh::mm::ss" or "mm::ss" or "ss"
     * @return time in seconds
     * @throws TimeFormatException - in case of wrong time format
     */
	public static int stringToInt(String strTime) throws TimeFormatException  {
		Time time = new Time(strTime);
        return time.hours*3600+time.minutes*60+time.seconds;
    }
	


}
